package com.bmf.module.testQuestions.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bmf.constant.AdminResultEnum;
import com.bmf.core.result.PageResponse;
import com.bmf.enums.ExaminationTypeEnum;
import com.bmf.module.examination.entity.Examination;
import com.bmf.module.examination.entity.FixedTestQuestion;
import com.bmf.module.examination.entity.SelectionStrategyQuestion;
import com.bmf.module.examination.service.ExaminationService;
import com.bmf.module.examination.service.FixedTestQuestionService;
import com.bmf.module.examination.service.SelectionStrategyQuestionService;
import com.bmf.module.testQuestions.entity.QuestionType;
import com.bmf.module.testQuestions.entity.SmallQuestion;
import com.bmf.module.testQuestions.entity.SmallQuestionAnswer;
import com.bmf.module.testQuestions.mapper.SmallQuestionMapper;
import com.bmf.module.testQuestions.service.QuestionTypeService;
import com.bmf.module.testQuestions.service.SmallQuestionService;
import com.bmf.module.testQuestions.vo.*;
import com.bmf.utils.BeanCopyUtils;
import com.bmf.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * (SmallQuestion)表服务实现类
 *
 * @author makejava
 * @since 2022-11-29 18:14:04
 */
@Service("smallQuestionService")
public class SmallQuestionServiceImpl extends ServiceImpl<SmallQuestionMapper, SmallQuestion> implements SmallQuestionService {

    @Autowired
    private ExaminationService examinationService;

    @Autowired
    private FixedTestQuestionService fixedTestQuestionService;

    @Autowired
    private SelectionStrategyQuestionService selectionStrategyQuestionService;

    @Autowired
    private QuestionTypeService questionTypeService;


    @Override
    public PageResponse<QuestionResultVo> selectPage(QuestionPageVo questionPageVo) {
        LambdaQueryWrapper<SmallQuestion> wrapper = new LambdaQueryWrapper();
        wrapper.eq(SmallQuestion::getCreateId, SecurityUtils.getUserId());
        if(questionPageVo.getQuestionType()!=null){
            wrapper.eq(SmallQuestion::getQuestionType,questionPageVo.getQuestionType());
        }
        if(StrUtil.isNotBlank(questionPageVo.getContent())){
            wrapper.like(SmallQuestion::getContent, questionPageVo.getContent());
        }
        if(questionPageVo.getStartTime()!=null){
            wrapper.ge(SmallQuestion::getCreateTime, questionPageVo.getStartTime());
        }
        if(questionPageVo.getEndTime()!=null){
            wrapper.le(SmallQuestion::getCreateTime, questionPageVo.getEndTime());
        }
        if(questionPageVo.getDifficultyLevel()!=null){
            wrapper.eq(SmallQuestion::getDifficultyLevel, questionPageVo.getDifficultyLevel());
        }
        if(questionPageVo.getType()!=null){
            wrapper.eq(SmallQuestion::getType, questionPageVo.getType());
        }
        //查询试卷已经勾选的所有题目id
        //固定试卷
        List<Integer> ids = getExaminationSmallQuestion(questionPageVo.getExaminationId());
        if(CollUtil.isNotEmpty(ids)){
            wrapper.notIn(SmallQuestion::getId, ids);
        }
        Page<SmallQuestion> page = new Page(questionPageVo.getPageNo(),questionPageVo.getPageSize());
        page(page,wrapper);
        List<SmallQuestion> records = page.getRecords();
        if(CollUtil.isEmpty(records)){
            return new PageResponse<>(null,page.getTotal(),questionPageVo.getPageNo(),questionPageVo.getPageSize());
        }
        //查找分类
        List<Integer> types = records.stream().map(SmallQuestion::getType).distinct().collect(Collectors.toList());
        List<QuestionType> questionTypes = questionTypeService.listByIds(types);
        Map<Integer, String> map = null;
        if(CollUtil.isNotEmpty(questionTypes)){
            map = questionTypes.stream().collect(Collectors.toMap(QuestionType::getId, QuestionType::getName));
        }

        //将选项转换
        Map<Integer, String> finalMap = map;
        List<QuestionResultVo> collect = records.stream().map(s -> {
            QuestionResultVo questionResultVo = BeanCopyUtils.copyBean(s, QuestionResultVo.class);
            if (StrUtil.isNotBlank(s.getSmallQuestionAnswer())) {
                questionResultVo.setSmallQuestionAnswers(JSONArray.parseArray(s.getSmallQuestionAnswer(), SmallQuestionAnswer.class));
            }
            if(finalMap !=null){
                questionResultVo.setTypeName(finalMap.get(questionResultVo.getType()));
            }
            return questionResultVo;
        }).collect(Collectors.toList());
        return new PageResponse<>(collect,page.getTotal(),questionPageVo.getPageNo(),questionPageVo.getPageSize());
    }

    private List<Integer> getExaminationSmallQuestion(Integer examinationId) {
        if(examinationId == null){
            return null;
        }
        Examination byId = examinationService.getById(examinationId);
        if(byId.getMold().equals(ExaminationTypeEnum.FIXED.getCode())){
            //固定试卷
            LambdaQueryWrapper<FixedTestQuestion> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(FixedTestQuestion::getExaminationId, examinationId);
            List<FixedTestQuestion> list = fixedTestQuestionService.list(wrapper);
            if(CollUtil.isNotEmpty(list)){
                return list.stream().map(FixedTestQuestion::getSmallQuestionId).collect(Collectors.toList());
            }
            return null;
        }else{
            //随机试卷
            LambdaQueryWrapper<SelectionStrategyQuestion> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SelectionStrategyQuestion::getExaminationId, examinationId);
            List<SelectionStrategyQuestion> list = selectionStrategyQuestionService.list(wrapper);
            if(CollUtil.isNotEmpty(list)){
                return list.stream().map(SelectionStrategyQuestion::getSmallQuestionId).filter(s->s!=null).collect(Collectors.toList());
            }
            return null;
        }
    }

    @Override
    public Integer insert(QuestionCreateVo questionCreateVo) {
        SmallQuestion smallQuestion = BeanCopyUtils.copyBean(questionCreateVo, SmallQuestion.class);
        smallQuestion.setCreateId(SecurityUtils.getUserId());
        if(CollUtil.isNotEmpty(questionCreateVo.getSmallQuestionAnswers())){
            smallQuestion.setSmallQuestionAnswer(JSONArray.toJSONString(questionCreateVo.getSmallQuestionAnswers()));
        }
        save(smallQuestion);
        return smallQuestion.getId();
    }

    @Override
    public void update(QuestionUpdateVo questionUpdateVo) {
        SmallQuestion smallQuestion = BeanCopyUtils.copyBean(questionUpdateVo, SmallQuestion.class);
        if(CollUtil.isNotEmpty(questionUpdateVo.getSmallQuestionAnswers())){
            smallQuestion.setSmallQuestionAnswer(JSONArray.toJSONString(questionUpdateVo.getSmallQuestionAnswers()));
        }
        updateById(smallQuestion);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(List<Integer> ids) {
        boolean b = removeByIds(ids);
        AdminResultEnum.DELETE_EXCEPTION.assertIsTrue(b);
        //1.删除选择了此题目的关联关系
        //1.1固定试卷
        fixedTestQuestionService.deleteBySmallQuestionIds(ids);
        //1.2随机试卷
        selectionStrategyQuestionService.deleteBySmallQuestionIds(ids);
    }

    @Override
    public QuestionResultVo selectOne(Integer id) {
        SmallQuestion byId = getById(id);
        if(byId==null) {
            return null;
        }
        QuestionResultVo questionResultVo = BeanCopyUtils.copyBean(byId, QuestionResultVo.class);
        if(StrUtil.isNotBlank(byId.getSmallQuestionAnswer())){
            questionResultVo.setSmallQuestionAnswers(JSONArray.parseArray(byId.getSmallQuestionAnswer(),SmallQuestionAnswer.class));
        }
        return questionResultVo;
    }

    @Override
    public List<QuestionResultVo> selectByIds(List<Integer> ids) {
        List<SmallQuestion> smallQuestions = listByIds(ids);
        if(CollUtil.isEmpty(smallQuestions)){
            return null;
        }
        //将选项转换
        List<QuestionResultVo> collect = smallQuestions.stream().map(s -> {
            QuestionResultVo questionResultVo = BeanCopyUtils.copyBean(s, QuestionResultVo.class);
            if (StrUtil.isNotBlank(s.getSmallQuestionAnswer())) {
                questionResultVo.setSmallQuestionAnswers(JSONArray.parseArray(s.getSmallQuestionAnswer(), SmallQuestionAnswer.class));
            }
            return questionResultVo;
        }).collect(Collectors.toList());
        return collect;
    }

    @Override
    public boolean existByType(Integer topic, Integer questionType) {
        LambdaQueryWrapper<SmallQuestion> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SmallQuestion::getType, topic).eq(SmallQuestion::getQuestionType, questionType);
        long count = count(wrapper);
        if(count==0){
            return false;
        }
        return true;
    }
}
